#ifndef _CHARACTER_H_DACHI_
#define _CHARACTER_H_DACHI_

#include "../Util.h"
#include "../Items/Weapon.h"
#include "../Items/Armor.h"
#include "../Items/OtherItem.h"
#include "../Items/Item.h"
#include <vector>
#include <cstdio>
#include <iostream>
#include <string>
#include <fstream>
#include "../Progress.h"
#include <map>

struct equipped{
	
	equipped();
	
	Weapon* defaultWeapon();
	Armor* defaultArmor();
	OtherItem* defaultOtherItem();
	
	Weapon* weapon;
	Armor* armor;
	OtherItem* other1;
	OtherItem* other2;
	OtherItem* other3;
};

struct dialog{
	public:
	struct req{
		progress p;
		bool modifier;
	};
	
	friend bool saveDialog (dialog&, std::ofstream&);
	friend bool loadDialog(std::vector<dialog>&, std::ifstream &);
	
	dialog(std::vector<req> r, std::string d, Progress::ach a):
	required(r), 
	dia(d),
	achievement(a)
	{	}
	std::vector<req> required;
	std::string dia;
	Progress::ach achievement;
	
};

class Character{

public:

Character(std::string name, std::string race,  bool is_male,Progress::ach killAch , int voice_pitch, int level, int exp_since_level_up, bool hostile);

~Character();

virtual void sleep() = 0;
void talk(Character * player);

virtual void getStatus() = 0;

void printEquipment();

void defend(int dmg, bool mag = false);

virtual int doAttack(bool mag = false) = 0;

virtual int attackPossible() = 0;

virtual void gather(bool mana = false) = 0;

virtual std::vector<cmdalt> get_Battle_alternatives() = 0;
virtual void levelUp() = 0;

bool battle(Character * player, bool playerAttack); 

virtual bool equippable(Item& item) = 0;

virtual void setInitialAttributes() = 0;

virtual std::string getType() = 0;

bool equipItem(Item& item, bool dialog = true);

bool equipItem(OtherItem& item, bool dialog = true);

bool changeEquipment(Item& oldItem, Item& newItem);

std::vector<cmdalt> get_equip_alternatives(Item& item1, Item& item2);
std::vector<cmdalt> get_deequip_alternatives();

bool equipItem(Weapon& item, bool dialog = true);

bool equipItem(Armor& item, bool dialog = true);
virtual int getConsumption(bool mag) = 0;
int getHP();

void addMaxHP(int change);

int getMagDef();

void addDef(int change);

void addHP(int change);

int getMaxHP();

int getexp();

int getDef();

void addExperience(int, bool = true);

int getLevel();

bool getGender();

int getPitch();

friend bool saveCharacter (Character&, std::ofstream&);
friend Character* loadCharacter(std::ifstream &);

std::string name;
std::string race;
Progress::ach kill;
Weapon* getEquippedWeapon();

bool achieved(progress p);
void setAchieved(Progress::ach p);

void setDialogs(std::vector<dialog> d);
bool isHostile();

virtual void getStatusAllAttributes() = 0;

std::string getTrashTalk(std::string inslut = "");
void defaultTrashTalk();
std::vector<cmdalt> get_loot_alternatives();
void loot(Character * player);
void setTrashTalk(std::vector<std::string> trash);

protected:
Character():
kill(NONE,0)
{defaultTrashTalk();}

enum { EXP_POINTS_PER_LEVEL = 10 };

int getBonus(int attr);

int HP;
int maxHP;
int exp;
int def;
int level;
bool male;
int pitch;
int magDef;
bool hostile;

std::vector<std::string> trashTalk;
std::vector<dialog> dialogs;
Progress * prog;
equipped equipment;
std::map <std::string, std::string> defInsults;
};

#endif
